package com.example.xd.model_video.videoeditlib.editVideoPlay;

import android.app.Activity;
import android.app.Application;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.res.AssetFileDescriptor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.AudioManager;
import android.media.MediaFormat;
import android.media.MediaPlayer;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.AttrRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.NotificationCompat;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;


import com.alibaba.android.arouter.launcher.ARouter;
import com.example.xd.model_video.R;
import com.example.xd.model_video.videoeditlib.Constants;

import org.litepal.crud.DataSupport;

import java.io.File;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;

import VideoHandle.OnEditorListener;

import static com.example.xd.model_video.videoeditlib.Constants.EDITING_COMPLETE;


/**
 * Created by cangc on 2018/3/12.
 */

public class EditVideoPlayer extends FrameLayout implements VideoFilterView.OnSaveProgress {

    private static final String TAG = EditVideoPlayer.class.getSimpleName();
    private static final int MSG_UPDATE_DIALOG = 2018;
    private static final int EDIT_COMPLETE_NOTIFY = 1001;
    private Context mContext;
    private VideoFilterView mVideoView;
    private ImageView mPlay;
    private TextView mCurrentTime;
    private TextView mTotalLength;
    private SeekBar seekBar;

    // 更新进度消息
    private static final int MSG_UPDATE_SEEK = 10086;
    private static final int MAX_VIDEO_SEEK = 1000;
    private String mOutputTempleFile = Constants.APPLICATION_PATH + "output_temp.mp4";
    private String mOutputFile = Constants.APPLICATION_PATH + "output.mp4";
    //视频时长
    private int video_duration = 0;
    private int currentPos = 0;
    private ExtractVideoInfoUtil ex;
    private MediaPlayer mediaPlayer;
    private String source;

    private Handler mHandler = new MyHandler(this);

    private static class MyHandler extends Handler {

        private WeakReference<EditVideoPlayer> playerWeakReference;

        MyHandler(EditVideoPlayer player) {
            playerWeakReference = new WeakReference<>(player);
        }

        @Override
        public void handleMessage(Message msg) {
            if (msg.what == MSG_UPDATE_SEEK) {
                //更新seekbar视图
                int pos = 0;
                try {
                    pos = playerWeakReference.get().setSeekBarProgress();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                msg = obtainMessage(MSG_UPDATE_SEEK);
                sendMessageDelayed(msg, 100 - (pos % 100));
            }
            if (msg.what == MSG_UPDATE_DIALOG) {
                float progress = (float) msg.obj;
                int load_pro = 50 + (int) (progress * 100);
                if (load_pro <= 100) {

                }
            }
        }
    }

    private String videoPath;
    private float mRawVolume;
    private float mNewVolume;

    public EditVideoPlayer(@NonNull Context context) {
        super(context);
        mContext = context;
        initView();
    }

    public EditVideoPlayer(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        mContext = context;
        initView();
    }

    public EditVideoPlayer(@NonNull Context context, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mContext = context;
        initView();
    }

    public void initView() {
        View.inflate(mContext, R.layout.edit_video_player, this);
        mediaPlayer = new MediaPlayer();
        mVideoView = (VideoFilterView) findViewById(R.id.edit_video_view);
        mPlay = (ImageView) findViewById(R.id.edit_video_play);
        mCurrentTime = (TextView) findViewById(R.id.edit_video_time);
        mTotalLength = (TextView) findViewById(R.id.edit_video_total_length);
        seekBar = (SeekBar) findViewById(R.id.edit_seek_bar);
        seekBar.setMax(MAX_VIDEO_SEEK);
        seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            int mTargetPosition;

            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                int duration = Integer.parseInt(ex.getVideoLength());
                // 计算目标位置
                mTargetPosition = (duration * progress) / MAX_VIDEO_SEEK;
                mCurrentTime.setText(generateTime(mTargetPosition));
                currentPos = progress;
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
                mHandler.removeMessages(MSG_UPDATE_SEEK);
            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                mVideoView.seekTo(mTargetPosition);
                if (source != null) {
                    if (mTargetPosition <= mediaPlayer.getDuration())
                        mediaPlayer.seekTo(mTargetPosition);
                    else {
                        while (mTargetPosition - mediaPlayer.getDuration() > 0) {
                            mTargetPosition = mTargetPosition - mediaPlayer.getDuration();
                        }
                        mediaPlayer.seekTo(mTargetPosition);
                    }
                }
                mHandler.sendEmptyMessageDelayed(MSG_UPDATE_SEEK, 500);
            }
        });
        mPlay.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mVideoView.isVideoPlaying()) {
                    mPlay.setImageResource(R.drawable.icon_edit_play);
                    pause();
                } else {
                    mPlay.setImageResource(R.drawable.icon_edit_pause);
                    start();

                }
            }
        });
        mVideoView.setOnPreparedListener(new MovieRenderer.PreparedListener() {
            @Override
            public void onPrepared(MediaPlayer mp) {
                mHandler.sendEmptyMessage(MSG_UPDATE_SEEK);
                video_duration = mp.getDuration();
            }
        });
        mVideoView.setOnCompletionListener(new MovieRenderer.CompletionListener() {
            @Override
            public void onCompletion(MediaPlayer mp) {
                mHandler.sendEmptyMessage(MSG_UPDATE_SEEK);
                if (source != null)
                    mediaPlayer.seekTo(0);
            }
        });
        mVideoView.setOnSaveProgress(this);
        mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
            @Override
            public void onPrepared(MediaPlayer mp) {
                if (canChangeSource) {
                    mediaPlayer.start();
                    mediaPlayer.seekTo(mVideoView.getCurrentPosition());
                }
            }
        });
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int wigth = MeasureSpec.getSize(widthMeasureSpec);
        int height = wigth * 9 / 16;
        int childwigthMeasureSpec = MeasureSpec.makeMeasureSpec(wigth, MeasureSpec.EXACTLY);
        int childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
        measureChildren(childwigthMeasureSpec, childHeightMeasureSpec);
        setMeasuredDimension(wigth, height);
    }

    public EditVideoPlayer setVideoPath(String url) {
        ConfigUtils.getInstance().setVideoPath(url);
        ex = new ExtractVideoInfoUtil(url, mContext);
        video_duration = Integer.parseInt(ex.getVideoLength());
        mTotalLength.setText(generateTime(video_duration));
        MediaFormat format = ConfigUtils.getInstance().getMediaFormat();
        if (format == null) {
            Toast.makeText(mContext, "Video Parsing Error", Toast.LENGTH_SHORT).show();
        }

        int videoFrameRate = 30;
        try {
            videoFrameRate = format.getInteger(MediaFormat.KEY_FRAME_RATE);
        } catch (Exception e) {
            e.printStackTrace();
        }
        int frameInterval = 1000 / videoFrameRate;
        ConfigUtils.getInstance().setFrameInterval(frameInterval);
        return this;
    }

    public void start() {
        if (!mVideoView.isPlaying()) {
            mPlay.setImageResource(R.drawable.icon_edit_pause);
            mVideoView.resume();
            mHandler.sendEmptyMessage(MSG_UPDATE_SEEK);
        }
        if (source != null && !mediaPlayer.isPlaying()) {
            mediaPlayer.seekTo(mVideoView.getCurrentPosition());
            mediaPlayer.start();
        }
    }

    public void pause() {
        if (mVideoView.isPlaying()) {
            mVideoView.pause();
            mHandler.removeMessages(MSG_UPDATE_SEEK);
        }
        if (source != null && mediaPlayer.isPlaying()) {
            mediaPlayer.pause();
        }
    }

    public void pauseMediaplayer() {
        if (source != null && mediaPlayer.isPlaying()) {
            mediaPlayer.pause();
            mPlay.setImageResource(R.drawable.icon_edit_play);
        }
    }

    public void startMediaplayer() {
        if (source != null && mediaPlayer != null && !mediaPlayer.isPlaying()) {
            mediaPlayer.start();
            mediaPlayer.seekTo(mVideoView.getCurrentPosition());
            mPlay.setImageResource(R.drawable.icon_edit_pause);
        }
    }

    public int getCurrentPos() {
        return mVideoView.getCurrentPosition();
    }

    public void setOldVolume(float volume) {
        this.mRawVolume = volume;
        mVideoView.setVolume(volume);
    }

    public void setNewVolume(float volume) {
        this.mNewVolume = volume;
        if (mediaPlayer != null)
            mediaPlayer.setVolume(volume, volume);
    }

    public void startRecord(ArrayList<String> path, ArrayList<TextViewUnit> textViewUnits, ArrayList<PicViewUnit> picList) {
        this.pathList = path;
        this.textViewUnits = textViewUnits;
        this.picViewUnits = picList;
        mVideoView.pause();
        if (source != null)
            mediaPlayer.pause();
        mHandler.removeMessages(MSG_UPDATE_SEEK);
        mVideoView.startRecord();
        String phoneNumber = SPUtils.getInstance().getString("phoneNumber", "");
        String userId = SPUtils.getInstance().getString("userId", "");
        DataSupport.deleteAll(VideoItemTB.class, "phoneNumber = ? and status = ?", userId, Constants.EDITING_VIDEO + "");
        VideoItemTB videoItemTB = DataSupport.where("phoneNumber = ? and status = ?", userId, "2").findFirst(VideoItemTB.class);
        videoID = videoItemTB.getVideoId();
        videoPath = videoItemTB.getVideoURL();
        videoItemTB.setStatus(Constants.EDITING_VIDEO);
        videoItemTB.updateAll("phoneNumber = ? and videoId = ?", userId, videoID);
        isFailure = false;
        timer = new Timer();
        timer.schedule(timerTask, 300, 1500);
        ARouter.getInstance().build("/main/main").navigation();
        ARouter.getInstance().build("/videoedit/MyWorksActivity").navigation();

    }

    private boolean isFailure = false;
    TimerTask timerTask = new TimerTask() {
        @Override
        public void run() {
            String phoneNumber = SPUtils.getInstance().getString("phoneNumber", "");
            String userId = SPUtils.getInstance().getString("userId", "");
            VideoItemTB videoItemTB = new VideoItemTB();
            if (isFailure) {
                videoItemTB.setProgress(0);
                videoItemTB.setStatus(Constants.EDITED_VIDEO);
            } else {
                if (editProgress >= 0 && editProgress <= 100)
                    videoItemTB.setProgress(editProgress);
            }
            videoItemTB.updateAll("phoneNumber = ? and videoId = ?", userId, videoID);
            Intent intent = new Intent();
            intent.setAction("UPDATE_EDIT_PROGRESS");
            intent.putExtra("videoId", videoID);
            mContext.sendBroadcast(intent);
            if (isFailure) {
                try {
                    timerTask.cancel();
                    timer.cancel();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    };

    Timer timer;

    public int setSeekBarProgress() {
        int postion = mVideoView.getCurrentPosition();
        int pos = MAX_VIDEO_SEEK * postion / video_duration;
        seekBar.setProgress(pos);
        mCurrentTime.setText(generateTime(postion));
        return postion;
    }

    public void setVideoProgress(int msc) {
        mVideoView.seekTo(msc);
        if (source != null)
            mediaPlayer.seekTo(msc);
        setSeekBarProgress();
    }

    /**
     * 时长格式化显示
     */
    public static String generateTime(int time) {
        int totalSeconds = time / 1000;
        int seconds = totalSeconds % 60;
        int minutes = totalSeconds / 60;
        return minutes > 99 ? String.format("%d:%02d", minutes, seconds) : String.format("%02d:%02d", minutes, seconds);
    }

    public VideoFilterView getmVideoView() {
        return mVideoView;
    }

    private boolean canChangeSource = true;

    public void setMediaPlayer(String source) {
        try {
            canChangeSource = this.source == null || mediaPlayer.isPlaying();
        } catch (Exception e) {
            canChangeSource = true;
        }
        mediaPlayer.reset();
        this.source = source;
        if (source == null)
            return;
        try {
            if (source.contains("asset")) {
                String fileName = source.substring(22);
                AssetFileDescriptor descriptor = getContext().getAssets().openFd(fileName);
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                    mediaPlayer.setDataSource(descriptor);
                } else {
                    OCRUtils.assets2SD(getContext(), Constants.APPLICATION_PATH + "temp.mp3", fileName);
                    mediaPlayer.setDataSource(Constants.APPLICATION_PATH + "temp.mp3");
                }
            } else
                mediaPlayer.setDataSource(source);
            mediaPlayer.prepare();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private int editProgress;

    ArrayList<String> pathList;
    ArrayList<TextViewUnit> textViewUnits;
    ArrayList<PicViewUnit> picViewUnits;

    @Override
    public void onProgress(int progress) {
        if (progress / 2 > 0 && progress / 2 != 1)
            editProgress = progress / 2;
    }

    @Override
    public void onComplete() {
        //输出视频高度
        final String mp3temp = Constants.APPLICATION_PATH + "temp.mp3";
        String musicPath;
        if (source != null) {
            if (source.contains("asset")) {
                OCRUtils.assets2SD(getContext(), mp3temp, source.substring(22));
            } else {
                FileUtil.renameFile(source, mp3temp);
            }
            musicPath = mp3temp;
        } else {
            musicPath = Constants.APPLICATION_PATH + "/抒情 - 一克拉的眼泪.mp3";
            mNewVolume = 0;
        }

        EpEditor.music(mOutputFile, musicPath, mOutputTempleFile, mRawVolume * 2, mNewVolume * 2, new OnEditorListener() {
            @Override
            public void onSuccess() {
                File file = new File(mp3temp);
                file.delete();
                //TODO
//                startSubtitleMix();

            }

            @Override
            public void onFailure() {
                isFailure = true;
                File file = new File(mp3temp);
                file.delete();
            }

            @Override
            public void onProgress(float progress) {
                //这里获取处理进度
                Log.v("EditPlayer", progress + "");
            }
        });
    }

    public static int[] getImageWidthHeight(String path) {
        BitmapFactory.Options options = new BitmapFactory.Options();

        /**
         * 最关键在此，把options.inJustDecodeBounds = true;
         * 这里再decodeFile()，返回的bitmap为空，但此时调用options.outHeight时，已经包含了图片的高了
         */
        options.inJustDecodeBounds = true;
        Bitmap bitmap = BitmapFactory.decodeFile(path, options); // 此时返回的bitmap为null
        /**
         *options.outHeight为原始图片的高
         */
        return new int[]{options.outWidth, options.outHeight};
    }

    private String videoID;

    /**
     * @param activityCount Application.getActivityCount()
     * @param context       Application.getContext()
     * @param activity      UpLoadActivity.class
     */
    public void startSubtitleMix(int activityCount, Context context, Activity activity) {
        EpVideo epVideo = new EpVideo(mOutputTempleFile);
        EpDraw epDraw0 = new EpDraw(Constants.APPLICATION_PATH + "/1.png", 0, 0, 1, 1, false);
        epVideo.addDraw(epDraw0);
        epVideo.clip(0, Integer.parseInt(ex.getVideoLength()) / 1000f);
        for (int i = 0; i < pathList.size(); i++) {
            int[] wh = getImageWidthHeight(pathList.get(i));
            float start = (float) textViewUnits.get(i).getLeftProgress();
            int end = (int) textViewUnits.get(i).getRightProgress();
            int x = (int) textViewUnits.get(i).getX();
            int y = (int) textViewUnits.get(i).getY();
            if (start == 0)
                start = 500f;
            EpDraw epDraw = new EpDraw(pathList.get(i), x, y, wh[0], wh[1], false, start / 1000f, end / 1000);
            epVideo.addDraw(epDraw);
        }
        FileUtil.createDir(Constants.APPLICATION_GIF);
        for (PicViewUnit picViewUnit : picViewUnits) {
            int picwidth = picViewUnit.getWidth();
            int picheight = picViewUnit.getHeight();
            int x = (int) picViewUnit.getX();
            int y = (int) picViewUnit.getY();
            float start = (float) picViewUnit.getLeftProgress();
            int end = (int) picViewUnit.getRightProgress();
            if (start == 0)
                start = 500f;
            if (picViewUnit.getResourceId().endsWith("gif")) {
                String source = picViewUnit.getResourceId();
                OCRUtils.assets2SD(getContext(), Constants.APPLICATION_GIF + source.substring(26), source.substring(22));
                EpDraw epDraw = new EpDraw(Constants.APPLICATION_GIF + source.substring(26), x, y, picwidth, picheight, true, start / 1000f, end / 1000);
                epVideo.addDraw(epDraw);
            } else {
                EpDraw epDraw = new EpDraw(picViewUnit.getResourceId(), x, y, picwidth, picheight, false, start / 1000f, end / 1000);
                epVideo.addDraw(epDraw);
            }
        }
        EpEditor.OutputOption outputOption = new EpEditor.OutputOption(mOutputFile);
        outputOption.bitRate = 2048;
        EpEditor.exec(epVideo, outputOption, new OnEditorListener() {
            @Override
            public void onSuccess() {
                mVideoView.setCombine(false);
                mHandler.removeMessages(MSG_UPDATE_DIALOG);
                mHandler.removeMessages(MSG_UPDATE_SEEK);
                timerTask.cancel();
                timer.cancel();
                String phoneNumber = SPUtils.getInstance().getString("phoneNumber", "");
                String userId = SPUtils.getInstance().getString("userId", "");
                VideoItemTB videoItemTB = new VideoItemTB();
                videoItemTB.setToDefault("progress");
                videoItemTB.setStatus(Constants.EDITED_VIDEO);
                String path = Constants.APPLICATION_VIDEO_SAVE_PATH + System.currentTimeMillis() + ".mp4";
                FileUtil.renameFile(mOutputFile, path);
                Bitmap thumbBitmap = VideoFrameUtil.getVideoFirstFrame(path);
                String videoThumbPath = PictureUtils.saveImageToSD(thumbBitmap, Constants.APPLICATION_VIDEO_THUMB);
                videoItemTB.setVideoURL(path);
                videoItemTB.setVideoThumbURL(videoThumbPath);
                videoItemTB.updateAll("phoneNumber = ? and videoId = ?", userId, videoID);
                Intent intent = new Intent();
                intent.setAction("UPDATE_EDIT_PROGRESS");
                intent.putExtra("videoId", videoID);

                mContext.sendBroadcast(intent);
                if (activityCount > 0) {
//                    Intent dialogIntent = new Intent(getContext(), DialogActivity.class);
//                    dialogIntent.putExtra("type", DialogActivity.EDITING_COMPLETE);
//                    dialogIntent.putExtra("id", videoID);
//                    getContext().startActivity(dialogIntent);
                    ARouter.getInstance().build("/appbaselib/DialogActivity").withInt("type", EDITING_COMPLETE).withString("id", videoID).navigation();
                } else {
                    Intent contentIntent = new Intent(context, activity.getClass());
                    contentIntent.putExtra("id", videoID);
                    contentIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, contentIntent, PendingIntent.FLAG_ONE_SHOT);
                    NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
                    builder.setSmallIcon(R.drawable.splash_logo)
                            .setAutoCancel(true)
                            .setContentIntent(pendingIntent)
                            .setFullScreenIntent(pendingIntent, true)
                            .setContentTitle("视频合成成功");
                    NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
                    if (notificationManager != null) {
                        notificationManager.notify(EDIT_COMPLETE_NOTIFY, builder.build());
                    }
                }
            }

            @Override
            public void onFailure() {
                isFailure = true;
                Log.v(TAG, "failure");
            }

            @Override
            public void onProgress(float progress) {
                //这里获取处理进度

                editProgress = 50 + (int) (progress / 2 * 100);
            }
        });
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float y = event.getY();
        int bar_height = findViewById(R.id.video_control_bar).getHeight();
        int height = getHeight();
        if (y > height - bar_height) {
            return true;
        } else {
            return super.onTouchEvent(event);
        }
    }

    public void setSilence(boolean b) {
        if (b)
            mediaPlayer.setVolume(0, 0);
        else {
            AudioManager audioManager = (AudioManager) getContext().getSystemService(Service.AUDIO_SERVICE);
            mediaPlayer.setVolume(audioManager.getStreamVolume(AudioManager.STREAM_SYSTEM), audioManager.getStreamVolume(AudioManager.STREAM_SYSTEM));
        }
    }
}
